package com.wang.cloud.manage.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.cloud.manage.domain.entity.RoleMenuRelationEntity;
import com.wang.cloud.manage.domain.vo.RoleMenuIdsVo;
import com.wang.cloud.manage.mapper.RoleMenuRelationMapper;
import com.wang.cloud.manage.service.IRoleMenuRelationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统-角色-菜单关联表 服务实现类
 * </p>
 *
 * @author wy
 * @since 2024-07-15
 */
@Service
public class RoleMenuRelationServiceImpl extends ServiceImpl<RoleMenuRelationMapper, RoleMenuRelationEntity> implements IRoleMenuRelationService {

    @Override
    public List<Long> queryMenuIdsByRoleId(Long roleId) {
        List<RoleMenuRelationEntity> list = this.lambdaQuery()
                .eq(RoleMenuRelationEntity::getRoleId, roleId)
                .select(RoleMenuRelationEntity::getMenuId)
                .list();
        return list.stream()
                .map(RoleMenuRelationEntity::getMenuId)
                .collect(Collectors.toList());
    }

    @Override
    public RoleMenuIdsVo queryMenuIdsVoByRoleId(Long roleId) {
        List<RoleMenuRelationEntity> list = this.lambdaQuery()
                .eq(RoleMenuRelationEntity::getRoleId, roleId)
                .select(RoleMenuRelationEntity::getMenuId, RoleMenuRelationEntity::getType)
                .list();

        List<Long> halfMenuIds = list.stream()
                .filter(bean -> Objects.equals(bean.getType(), 1))
                .map(RoleMenuRelationEntity::getMenuId)
                .collect(Collectors.toList());

        List<Long> fullMenuIds = list.stream()
                .filter(bean -> Objects.equals(bean.getType(), 2))
                .map(RoleMenuRelationEntity::getMenuId)
                .collect(Collectors.toList());

        RoleMenuIdsVo vo = new RoleMenuIdsVo();
        vo.setId(roleId);
        vo.setFullMenuIds(fullMenuIds);
        vo.setHalfMenuIds(halfMenuIds);
        return vo;

    }


    @Override
    public Map<Long, List<Long>> queryMenuIdsByRoleIds(Collection<Long> roleIds) {
        if (ObjectUtil.isEmpty(roleIds)) {
            return Collections.emptyMap();
        }
        List<RoleMenuRelationEntity> list = this.lambdaQuery()
                .in(RoleMenuRelationEntity::getRoleId, roleIds)
                .select(RoleMenuRelationEntity::getRoleId, RoleMenuRelationEntity::getMenuId)
                .list();
        Map<Long, List<Long>> collect = list.stream()
                .collect(
                        Collectors.groupingBy(RoleMenuRelationEntity::getRoleId,
                                Collectors.mapping(
                                        RoleMenuRelationEntity::getMenuId,
                                        Collectors.toList()
                                )));
        return collect;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveRoleMenus(Long roleId, Collection<Long> fullMenuIds, Collection<Long> halfMenuIds) {
        delByRoleId(roleId);
        List<RoleMenuRelationEntity> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(fullMenuIds)) {
            // 全选
            list.addAll(convertTo(roleId, fullMenuIds, 2));
        }
        if (CollectionUtil.isNotEmpty(halfMenuIds)) {
            // 半选
            list.addAll(convertTo(roleId, halfMenuIds, 1));
        }
        if (list.isEmpty()) {
            return Boolean.TRUE;
        }
        return this.saveBatch(list);
    }

    private List<RoleMenuRelationEntity> convertTo(Long roleId, Collection<Long> menuIds, Integer type) {
        if (CollectionUtil.isNotEmpty(menuIds)) {
            return menuIds.stream()
                    .distinct()
                    .filter(Objects::nonNull)
                    .map(menuId -> {
                        RoleMenuRelationEntity entity = new RoleMenuRelationEntity();
                        entity.setRoleId(roleId);
                        entity.setMenuId(menuId);
                        entity.setType(type);
                        return entity;
                    })
                    .collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delByRoleId(Long roleId) {
        return this.lambdaUpdate()
                .eq(RoleMenuRelationEntity::getRoleId, roleId)
                .remove();
    }

    @Override
    public Boolean delByMenuId(Long menuId) {
        return this.lambdaUpdate()
                .eq(RoleMenuRelationEntity::getMenuId, menuId)
                .remove();
    }

    @Override
    public Set<Long> queryRoleIdsByMenuId(Long menuId) {
        if (Objects.isNull(menuId)) {
            return Collections.emptySet();
        }
        List<RoleMenuRelationEntity> list = this.lambdaQuery()
                .eq(RoleMenuRelationEntity::getMenuId, menuId)
                .select(RoleMenuRelationEntity::getRoleId)
                .list();
        return list.stream()
                .map(RoleMenuRelationEntity::getRoleId)
                .collect(Collectors.toSet());
    }
}
